home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Panorama / Panorama - Disk 19D (1987-07-22)(Pacific North-West Amigas Club)[WB].zip / Panorama - Disk 19D (1987-07-22)(Pacific North-West Amigas Club)[WB].adf / HackBench / hbobj.c < prev    next >
C/C++ Source or Header  |  1987-07-14  |  21KB  |  660 lines

  1. /****************************************************************
  2. /*                                *
  3. /*    HackBench - Part 3 of 4 - hbobj.c - Object Routines     *
  4. /*                                *
  5. /*    Copyright (C) 1987 by Bill Kinnersley            *
  6. /*    CS Dept, Washington State Univ, Pullman, WA 99164    *
  7. /*                                *
  8. /*    Permission granted to redistribute this program        *
  9. /*    provided the copyright notice remains intact.        *
  10. /*    May not be used as part of any commercial product.    *
  11. /*                                *
  12. /****************************************************************/
  13.  
  14. #include "hb.h"
  15.  
  16. extern struct DosLibrary *DosBase;
  17. extern struct DosInfo *rnInfo;
  18. extern struct MsgPort *IDCMPPort, *WBPort;
  19. extern struct Window *wbWin, *curWin;
  20. extern struct DiskObject defDskObj;
  21. extern struct Menu *menuStrip;
  22. extern struct Gadget
  23.     vs_gad, hs_gad, ren_gad, up_gad, dm_gad, lm_gad, rm_gad;
  24. extern struct PropInfo hs_knob, vs_knob;
  25. extern USHORT zz_ptr[];
  26. extern char *title, *rindex();
  27. extern BPTR initialDir, getlock();
  28. extern short debug;
  29.  
  30. struct Rectangle rect = {4, 11};
  31.  
  32. struct List wbObjs, selObjs, utilObjs;
  33. short lastHeight=14, toolsRunning = 0, wbFlags = 0;
  34.  
  35. void *allocList();
  36. int drawobj(), compobj();
  37.  
  38. char *type[8] = {"", "DISK", "DRAWER", "TOOL", "PROJECT",
  39.     "GARBAGE", "DEVICE", "KICK"};
  40. char *empty = "";
  41.  
  42. struct IntuiText icon_txt = {1, 0, JAM2, 5, 0, NULL, NULL, NULL};
  43.  
  44. /* Manufacture a new WBObject with a given name, window, and parent */
  45. struct MyWBObject *makeObj(diskObj, name, w, parent)
  46. struct DiskObject *diskObj; char *name;
  47. struct Window *w; struct MyWBObject *parent; {
  48.     struct MyWBObject *obj;
  49.     char *buf, *p;
  50.     SHORT size, i, s;
  51.     struct Gadget *g;
  52.     struct Image *image;
  53.     USHORT *data;
  54.     struct MyDrawerData *dd;
  55.     struct NewWindow *nwd;
  56.  
  57.     if (!(obj= ALLOC(MyWBObject)))
  58.         {error("Can't allocate WB Object"); return;}
  59.     NewList(&obj->wo_FreeList.fl_MemList);
  60.     buf = allocList(obj, 31);
  61.     /* Space for 31 chars in case it's later renamed */
  62.     strcpy(buf, name);
  63.     obj->wo_Name = obj->wo_MasterNode.ln_Name = 
  64.     obj->wo_Siblings.ln_Name = obj->wo_SelectNode.ln_Name = buf;
  65.     AddTail(&wbObjs, obj);
  66.     obj->wo_IconWin = w;
  67.     obj->wo_Type = diskObj->do_Type;
  68.     if (diskObj->do_ToolTypes) {
  69.         for (i = 0; p = diskObj->do_ToolTypes[i]; i++) ;
  70.         obj->wo_ToolTypes = allocList(obj, 4*i);
  71.         for (i = 0; p = diskObj->do_ToolTypes[i]; i++) {
  72.             buf = allocList(obj, strlen(p)+1);
  73.             strcpy(buf, p);
  74.             obj->wo_ToolTypes[i] = buf;
  75.         }
  76.     }
  77.     if (diskObj->do_ToolWindow) {
  78.         buf = allocList(obj, strlen(diskObj->do_ToolWindow)+1);
  79.         strcpy(buf, diskObj->do_ToolWindow);
  80.         obj->wo_ToolWindow = buf;
  81.     }
  82.     if (diskObj->do_DefaultTool) {
  83.         buf = allocList(obj, strlen(diskObj->do_DefaultTool)+1);
  84.         strcpy(buf, diskObj->do_DefaultTool);
  85.         obj->wo_DefaultTool = buf;
  86.     }
  87.     obj->wo_StackSize = diskObj->do_StackSize;
  88.     obj->wo_CurrentX = diskObj->do_CurrentX;
  89.     obj->wo_CurrentY = diskObj->do_CurrentY;
  90.     if (diskObj->do_CurrentX==NO_ICON_POSITION) {
  91.         if (debug) printf("<%s>:No Icon Position\n", name);
  92.         obj->wo_CurrentX = 20; obj->wo_CurrentY = 10;
  93.         /* Should do better placement than this */
  94.     }
  95.     g = &diskObj->do_Gadget;
  96.     /* stc means structure copy */
  97. /*stc*/    obj->wo_Gadget = diskObj->do_Gadget;
  98.     image = allocList(obj, sizeof(struct Image));
  99. /*stc*/ *image = *(struct Image *)(diskObj->do_Gadget.GadgetRender);
  100.     obj->wo_Gadget.GadgetRender = (APTR)image;
  101.  
  102.     size = (image->Width/16) + ((image->Width%16)>0);
  103.     size *= image->Height * image->Depth;
  104.     data = allocList(obj, 2*size);
  105.     for (i=0; i<size; i++) data[i] = (image->ImageData)[i];
  106.     image->ImageData = data;
  107.  
  108.     image = allocList(obj, sizeof(struct Image));
  109.     if (diskObj->do_Gadget.SelectRender)
  110. /*stc*/        *image = *(struct Image *)(diskObj->do_Gadget.SelectRender);
  111.     else *image = *(struct Image *)(diskObj->do_Gadget.GadgetRender);
  112.     obj->wo_Gadget.SelectRender = (APTR)image;
  113.  
  114.     size = (image->Width/16) + ((image->Width%16)>0);
  115.     size *= image->Height * image->Depth;
  116.     data = allocList(obj, 2*size);
  117.  
  118.     if (diskObj->do_Gadget.SelectRender)
  119.         for (i=0; i<size; i++) data[i] = (image->ImageData)[i];
  120.     else
  121.         for (i=0; i<size; i++) data[i] = ~(image->ImageData)[i];
  122.     image->ImageData = data;
  123.  
  124.     if (diskObj->do_DrawerData) {
  125.         dd = allocList(obj, sizeof(struct MyDrawerData));
  126.         obj->wo_DrawerData = dd;
  127. /* stc */    dd->dd_NewWindow = diskObj->do_DrawerData->dd_NewWindow;
  128.         dd->dd_NewWindow.Title = obj->wo_Name;
  129.         NewList(&dd->dd_Children);
  130.         dd->dd_CurrentX = diskObj->do_DrawerData->dd_CurrentX;
  131.         dd->dd_CurrentY = diskObj->do_DrawerData->dd_CurrentY;
  132.         nwd = &dd->dd_NewWindow;
  133.         nwd->MinWidth = 90;
  134.         nwd->MinHeight = 40;
  135.         nwd->MaxWidth = nwd->MaxHeight = -1;
  136.         dd->dd_MinX = dd->dd_MinY = 0;
  137.         dd->dd_MaxX = nwd->Width - 14;
  138.         dd->dd_MaxY = nwd->Height - 9;
  139. /*stc*/     dd->dd_HorizScroll = hs_gad;
  140. /*stc*/        dd->dd_VertScroll = vs_gad;
  141. /*stc*/     dd->dd_UpMove = up_gad;
  142. /*stc*/     dd->dd_DownMove = dm_gad;
  143. /*stc*/     dd->dd_LeftMove = lm_gad;
  144. /*stc*/     dd->dd_RightMove = rm_gad;
  145. /*stc*/     dd->dd_HorizProp = hs_knob;
  146. /*stc*/     dd->dd_VertProp = vs_knob;
  147.         dd->dd_HorizScroll.GadgetRender = (APTR)&dd->dd_HorizImage;
  148.         dd->dd_HorizScroll.SpecialInfo = (APTR)&dd->dd_HorizProp;
  149.         dd->dd_VertScroll.GadgetRender = (APTR)&dd->dd_VertImage;
  150.         dd->dd_VertScroll.SpecialInfo = (APTR)&dd->dd_VertProp;
  151.         dd->dd_HorizScroll.NextGadget = &dd->dd_VertScroll;
  152.         dd->dd_VertScroll.NextGadget = &dd->dd_UpMove;
  153.         dd->dd_UpMove.NextGadget = &dd->dd_DownMove;
  154.         dd->dd_DownMove.NextGadget = &dd->dd_LeftMove;
  155.         dd->dd_LeftMove.NextGadget = &dd->dd_RightMove;
  156.         dd->dd_NewWindow.FirstGadget = &dd->dd_HorizScroll;
  157.     }
  158.     obj->wo_NameXOffset = (g->Width/2)-4*strlen(name);
  159.     obj->wo_NameYOffset = g->Height;
  160.     obj->wo_Parent = parent;
  161.     if (parent && parent->wo_DrawerData) {
  162.         AddHead(&parent->wo_DrawerData->dd_Children,
  163.             &obj->wo_Siblings);
  164.         if (debug) printf("Added %lx <%s> to %lx <%s>\n",
  165.             obj, obj->wo_Name, parent, parent->wo_Name);
  166.     }
  167.     return obj;
  168. }
  169.  
  170. /* Given a List, use off to find the objects,
  171. then perform fn on each object with parameter p1 */
  172. doList(list, off, fn, p1)
  173. struct List *list; long off; int (*fn)(); {
  174.     struct MyWBObject *obj;
  175.     struct Node *node;
  176.  
  177.     for (node=list->lh_Head; node->ln_Succ; node=node->ln_Succ) {
  178.         obj = OBJ(node,off);
  179.         (*fn)(obj, p1);
  180.     }
  181. }
  182.  
  183. /* Remove an object from the system */
  184. deleteobj(obj) struct MyWBObject *obj; {
  185.     struct MyDrawerData *dd;
  186.     struct MyWBObject *child;
  187.     struct Node *node;
  188.     long off;
  189.  
  190.     if (dd = obj->wo_DrawerData) {
  191.     if (dd->dd_DrawerWin) /* Shouldn't happen */
  192.         {printf("Can't delete me--I'm open\n"); return;}
  193.     if (dd->dd_Lock) {
  194.         if (debug) printf("deleteobj: Unlocking dd_Lock: <%s> %lx\n",
  195.         obj->wo_Name, dd->dd_Lock);
  196.         UnLock(dd->dd_Lock);
  197.         dd->dd_Lock = NULL;
  198.     }
  199.     while (node = RemHead(&dd->dd_Children)) {
  200.         child = OBJ(node, CHILD);
  201.         if (debug) printf("Found an orphan %lx\n", child);
  202.         child->wo_Parent = NULL;
  203.     }
  204.     }
  205.     if (debug) printf("Deleting %lx <%s> %lx\n", obj,
  206.     obj->wo_MasterNode.ln_Name, obj->wo_Lock);
  207.     if (obj->wo_Lock) {
  208.     if (debug) printf("deleteobj: Unlocking wo_Lock: <%s> %lx\n",
  209.         obj->wo_Name, obj->wo_Lock);
  210.     UnLock(obj->wo_Lock);
  211.     obj->wo_Lock = NULL;
  212.     }
  213.     FreeFreeList(&obj->wo_FreeList);
  214.     for (off=0; off<4; off++) {
  215.     node = (struct Node *)((long)obj + off*sizeof(struct Node));
  216.     if (node->ln_Succ) Remove(node);
  217.     }
  218.     FreeMem(obj, (long)sizeof(struct MyWBObject));
  219. }
  220.  
  221. struct DiskObject *getDisk(name) char *name; {
  222.     char buf[36];
  223.  
  224.     strcpy(buf, name);
  225.     strcat(buf,":Disk");
  226.     return GetDiskObject(buf);
  227. }
  228.  
  229. /* Initial installation of all Volumes on the Device List */
  230. findDisks() {
  231.     struct DeviceList *diDev, *ptr;
  232.     char diskName[31];
  233.  
  234.     diDev = (struct DeviceList *) BADDR(rnInfo->di_DevInfo);
  235.     for (ptr=diDev; ptr; ptr=(struct DeviceList *)BADDR(ptr->dl_Next)){
  236.         if (ptr->dl_Type==DLT_VOLUME) {
  237.         bs2cs(diskName, ptr->dl_Name);
  238.         if (debug) printf("<%s>\n", diskName);
  239.         instDisk(diskName);
  240.         }
  241.     }
  242. }
  243.  
  244. /* Install an object and icon for a disk */
  245. instDisk(diskName) char *diskName; {
  246.     struct DiskObject *dObj;
  247.     struct MyWBObject *obj;
  248.  
  249.     if (dObj = getDisk(diskName)) {
  250.         if (dObj->do_CurrentX==NO_ICON_POSITION)
  251.             dObj->do_CurrentX = 576;
  252.         if (dObj->do_CurrentY==NO_ICON_POSITION)
  253.             dObj->do_CurrentY = lastHeight;
  254.         obj = makeObj(dObj, diskName, wbWin, NULL);
  255.         FreeDiskObject(dObj);
  256.     }
  257.     else {
  258.         if (debug) printf("Default icon\n");
  259.         dObj = &defDskObj;
  260.         dObj->do_CurrentY = lastHeight;
  261.         obj = makeObj(dObj, diskName, wbWin, NULL);
  262.     }
  263.     drawobj(obj, NORM);
  264.     lastHeight += 22L;
  265.     /* Should try harder to find an empty spot */
  266. }
  267.  
  268. /* For debugging, print everybody on a List */
  269. dumplist(list, off) struct List *list; long off; {
  270.     struct Node *node;
  271.     struct MyWBObject *child;
  272.  
  273.     printf("---\n");
  274.     for (node=list->lh_Head; node->ln_Succ; node=node->ln_Succ) {
  275.         child = OBJ(node,off);
  276.         printf("%lx <%s>\n", node, node->ln_Name);
  277.     }
  278. }
  279.  
  280. /* Close a drawer object */
  281. closeobj(obj) struct MyWBObject *obj; {
  282.     struct MyDrawerData *dd;
  283.     struct Node *node;
  284.     struct MyWBObject *child;
  285.     struct FileLock mylock;
  286.     struct Region *reg;
  287.  
  288.     if (!(dd = obj->wo_DrawerData)) return;
  289.     if (!dd->dd_DrawerWin) return;
  290.     NewList(&utilObjs);
  291.     for (node=dd->dd_Children.lh_Head; node->ln_Succ;
  292.     node = node->ln_Succ) {
  293.     child = OBJ(node,CHILD);
  294.     if (debug) printf("child: %lx <%s>\n", child, child->wo_Name);
  295.     if (child->wo_IconWin==dd->dd_DrawerWin) { /* In this window */
  296.         if (child->wo_DrawerData) /* a drawer */ {
  297.         if (child->wo_DrawerData->dd_DrawerWin) {
  298.             if (debug) printf("Child open..retained\n");
  299.             child->wo_IconWin = NULL;
  300.             if (child->wo_SelectNode.ln_Succ) {
  301.             Remove(&child->wo_SelectNode);
  302.             child->wo_SelectNode.ln_Succ = NULL;
  303.             }
  304.             continue;
  305.         }
  306.         if (child->wo_DrawerData->dd_Children.lh_Head->ln_Succ) {
  307.             if (debug) {
  308.             printf("Child has children..retained\n");
  309.             printf("closeobj: grandchildren:");
  310.             dumplist(&child->wo_DrawerData->dd_Children, CHILD);
  311.             }
  312.             child->wo_IconWin = NULL;
  313.             continue;
  314.         }
  315.         }/* if drawer */
  316.         AddHead(&utilObjs, &child->wo_UtilityNode);
  317.     }/* if in window */
  318.     }/* for children */
  319.     doList(&utilObjs, UTIL, deleteobj); /* Kill the kids */
  320.     dd->dd_NewWindow.LeftEdge = dd->dd_DrawerWin->LeftEdge;
  321.     dd->dd_NewWindow.TopEdge = dd->dd_DrawerWin->TopEdge;
  322.     dd->dd_NewWindow.Width = dd->dd_DrawerWin->Width;
  323.     dd->dd_NewWindow.Height = dd->dd_DrawerWin->Height;
  324.     reg = InstallClipRegion(dd->dd_DrawerWin->WLayer, NULL);
  325.     DisposeRegion(reg);
  326.     closeWinSafely(dd->dd_DrawerWin);
  327.     dd->dd_DrawerWin = NULL;
  328.     if (dd->dd_Lock) {
  329.     if (debug) printf("closeobj: cd %lx\n", initialDir);
  330.     CurrentDir(initialDir);
  331.     if (debug) printf("closeobj: Unlocking dd_Lock <%s> %lx\n",
  332.         obj->wo_Name, dd->dd_Lock);
  333.     UnLock(dd->dd_Lock);
  334.     dd->dd_Lock = NULL;
  335.     }
  336. }
  337.  
  338. /* Remove an icon from the screen */
  339. clearobj(obj) struct MyWBObject *obj; {
  340.     struct Window *w;
  341.     struct MyDrawerData *dd;
  342.     long cx=0, cy=0;
  343.  
  344.     if ((w = obj->wo_IconWin)!=wbWin) {
  345.     dd = ((struct MyWBObject *)w->UserData)->wo_DrawerData;
  346.     cx = dd->dd_CurrentX;
  347.     cy = dd->dd_CurrentY;
  348.     }
  349.     if (debug) printf("clearobj: %lx <%s> win=%lx\n", obj, obj->wo_Name, w);
  350.     SetAPen(w->RPort, 0L);
  351.     RectFill(w->RPort,
  352.     obj->wo_CurrentX - cx, obj->wo_CurrentY + YOFF - cy,
  353.     obj->wo_CurrentX + obj->wo_Gadget.Width - cx,
  354.     obj->wo_CurrentY + obj->wo_Gadget.Height + YOFF - cy);
  355.     RectFill(w->RPort,
  356.     obj->wo_CurrentX + obj->wo_NameXOffset - cx,
  357.     obj->wo_CurrentY + obj->wo_NameYOffset + YOFF - cy,
  358.     obj->wo_CurrentX + obj->wo_NameXOffset +
  359.         8L*(long)strlen(obj->wo_Name) - cx,
  360.     obj->wo_CurrentY + obj->wo_NameYOffset + YOFF + 10L - cy);
  361.     SetAPen(w->RPort, 1L);
  362. }
  363.  
  364. /* Toggle an icon, highlighted <-> normal */
  365. compobj(obj) struct MyWBObject *obj; {
  366.     struct Window *w;
  367.     long cx=0, cy=0;
  368.     struct MyDrawerData *dd;
  369.  
  370.     if (debug) printf("comp: %lx <%s>\n", obj, obj->wo_Name);
  371.     if ((w = obj->wo_IconWin)!=wbWin) {
  372.         dd = ((struct MyWBObject *)w->UserData)->wo_DrawerData;
  373.         cx = dd->dd_CurrentX;
  374.         cy = dd->dd_CurrentY;
  375.     }
  376.     ClipBlit(w->RPort, obj->wo_CurrentX - cx, obj->wo_CurrentY - cy,
  377.         w->RPort, obj->wo_CurrentX - cx, obj->wo_CurrentY - cy,
  378.         (long)obj->wo_Gadget.Width, (long)obj->wo_Gadget.Height,
  379.         0x50L);
  380.     obj->wo_Flags ^= HIGH;    /* For use by refresh() */
  381. }
  382.  
  383. /* At position (x,y) see if an icon was hit and if so whom */
  384. struct MyWBObject *findObj(x, y, w) short x, y; struct Window *w; {
  385.     struct Node *node;
  386.     struct Gadget *gad;
  387.     struct MyWBObject *obj;
  388.     struct MyDrawerData *dd;
  389.     long cx=0, cy=0;
  390.  
  391.     if (w!=wbWin) {
  392.         dd = ((struct MyWBObject *)w->UserData)->wo_DrawerData;
  393.         cx = dd->dd_CurrentX;
  394.         cy = dd->dd_CurrentY;
  395.     }
  396.     /* Scan list in reverse order,
  397.     so that last icon drawn is first one found */
  398.     for (node=wbObjs.lh_TailPred; node->ln_Pred; node=node->ln_Pred) {
  399.         obj = (struct MyWBObject *)node;
  400.         if (w != obj->wo_IconWin) continue;
  401.         gad = &obj->wo_Gadget;
  402.         if ((x > (obj->wo_CurrentX-cx)) &&
  403.             (x < (obj->wo_CurrentX + gad->Width - cx)) &&
  404.             (y > (obj->wo_CurrentY + YOFF - cy)) &&
  405.             (y < (obj->wo_CurrentY + gad->Height + YOFF - cy)))
  406.             return obj;
  407.     }
  408.     return NULL;
  409. }
  410.  
  411. openobj(obj) struct MyWBObject *obj; {
  412.     struct Window *w;
  413.     struct MyDrawerData *dd;
  414.     char name[80];
  415.     struct Region *reg;
  416.     BPTR lock;
  417.  
  418.     if (debug) printf("openobj:%lx <%s>\n",obj, obj->wo_Name);
  419.     if (!(dd = obj->wo_DrawerData)) {
  420.         printf("What's this %s doing here??\n",type[obj->wo_Type]);
  421.         return;
  422.     }
  423.     if (dd->dd_DrawerWin) return; /* Already open */
  424.     SetPointer(curWin, zz_ptr, 19L, 16L, -7L, -8L);
  425.     dd->dd_NewWindow.Title = obj->wo_Name;
  426.     dd->dd_NewWindow.IDCMPFlags = 0;
  427.     if (!(w = OpenWindow(&dd->dd_NewWindow)))
  428.         {error("Couldn't open the drawer\n"); goto opcln;}
  429.     dd->dd_DrawerWin = w;
  430.     w->UserPort = IDCMPPort;
  431.     ModifyIDCMP(w, CLOSEWINDOW | GADGETUP | GADGETDOWN |
  432.         MENUPICK | NEWSIZE | MOUSEBUTTONS | REFRESHWINDOW);
  433.     SetMenuStrip(w, menuStrip);
  434.     SetWindowTitles(w, -1L, title);
  435.     reclip(w);
  436.     /* UserData holds a pointer back to the object */
  437.     w->UserData = (BYTE *)obj;
  438.  
  439.     lock = getlock(obj);
  440.     if (debug) printf("openobj: cd %lx\n", lock);
  441.     CurrentDir(lock);
  442.     if (!dd->dd_Lock) {
  443.         strcpy(name, obj->wo_Name);
  444.         if (obj->wo_Type==WBDISK) strcat(name,":");
  445.         dd->dd_Lock = Lock(name, ACCESS_READ);
  446.         if (debug) printf("openobj Locked <%s> %lx\n",
  447.             name, dd->dd_Lock);
  448.         if (!dd->dd_Lock) {
  449.             error("This drawer cannot be opened");
  450.             /* Probably an .info file all by itself */
  451.             reg = InstallClipRegion(w->WLayer, NULL);
  452.             DisposeRegion(reg);
  453.             closeWinSafely(w);
  454.             dd->dd_DrawerWin = NULL;
  455.             goto opcln;
  456.         }
  457.     }
  458.     dir(obj, w);
  459.     resize(w);
  460. opcln:    ClearPointer(curWin);
  461. }
  462.  
  463. /* Search a directory for .info files */
  464. dir(obj, w) struct MyWBObject *obj; struct Window *w; {
  465.     FILE *fd;
  466.     struct InfoData *id;
  467.     LONG success;
  468.     struct FileInfoBlock *m;
  469.     BPTR oldlock, newLock;
  470.     char *name, buf[80], buf2[80], *s;
  471.     struct DiskObject *dObj;
  472.     struct MyWBObject *wbObj;
  473.     struct Node *node;
  474.     struct MyDrawerData *dd;
  475.  
  476.     dd = obj->wo_DrawerData;
  477.     name = obj->wo_Name;
  478.     strcpy(buf, name);
  479.     strcat(buf,":");
  480.  
  481.     if (!(newLock = dd->dd_Lock)) {printf("No lock\n"); return;}
  482.     if (debug) printf("dir: cd %lx\n", newLock);
  483.     oldlock = CurrentDir(newLock);
  484.     /* If we were using the .info file itself: */
  485.     /*if (fd=fopen(".info","r")) {
  486.         if (fseek(fd, 16L, 0)!=-1) {
  487.         while (fgets(buf2, 70, fd)) {
  488.             buf2[strlen(buf2)-1]=0;
  489.             if (dObj=GetDiskObject(buf2)) {
  490.             obj = makeObj(dObj, buf2, w, obj);
  491.             doList(&selObjs, SEL, drawobj, NORM);
  492.             FreeDiskObject(dob);
  493.             }
  494.             else printf("can't get <%s>\n",buf2);
  495.         }
  496.         }
  497.         fclose(fd);
  498.         return;
  499.     }*/
  500.     if (!(id = ALLOC(InfoData)))
  501.         {error("Can't allocate id"); goto dirCln;}
  502.     if (!(success = Info(newLock, id)))
  503.         {error("Can't get info"); goto dirCln;}
  504.     if (!(m = ALLOC(FileInfoBlock)))
  505.         {error("Can't allocate m"); goto dirCln;}
  506.     if (!(success = Examine(newLock, m)))
  507.         {error("Can't examine directory"); goto dirCln;}
  508.     if (m->fib_DirEntryType<=0)
  509.         {error("Not a directory"); goto dirCln;}
  510.     NewList(&utilObjs);
  511.     while (success = ExNext(newLock, m)) {
  512.         strcpy(buf, m->fib_FileName);
  513.         if (s = rindex(buf,'.')) if (strcmp(s,".info")==0) {
  514.         *s = 0;
  515.         if ((*buf) && (strcmp(buf,"Disk"))) {
  516.             if (debug) printf("Looking for <%s>\n", buf);
  517.             if (node = FindName(&dd->dd_Children, buf)) {
  518.             wbObj = OBJ(node,CHILD);
  519.             if (debug) printf("Found child <%s> %lx\n",
  520.                 node->ln_Name, wbObj);
  521.             if (!wbObj->wo_IconWin)
  522.                 wbObj->wo_IconWin = dd->dd_DrawerWin;
  523.             AddTail(&utilObjs, &wbObj->wo_UtilityNode);
  524.             }
  525.             else if (dObj = GetDiskObject(buf)) {
  526.             wbObj = makeObj(dObj, buf, w, obj);
  527.             FreeDiskObject(dObj);
  528.             AddTail(&utilObjs, &wbObj->wo_UtilityNode);
  529.             }
  530.             else printf("Can't get <%s>\n", m->fib_FileName);
  531.         } /* if buf */
  532.         } /* if s */
  533.     } /* while */
  534.     doList(&utilObjs, UTIL, drawobj, NORM);
  535. dirCln:    if (m) FreeMem(m, (long)sizeof(struct FileInfoBlock));
  536.     if (id) FreeMem(id, (long)sizeof(struct InfoData));
  537. }
  538.  
  539. /* Draw an icon, either normal or hightlighted */
  540. drawobj(obj, mode) struct MyWBObject *obj; {
  541.     struct Window *w;
  542.     long cx=0, cy=0;
  543.     struct MyDrawerData *dd;
  544.     APTR im;
  545.  
  546.     if ((w = obj->wo_IconWin)!=wbWin) {
  547.         dd = ((struct MyWBObject *)w->UserData)->wo_DrawerData;
  548.         cx = dd->dd_CurrentX;
  549.         cy = dd->dd_CurrentY;
  550.     }
  551.     im = (mode & HIGH) ? obj->wo_Gadget.SelectRender :
  552.         obj->wo_Gadget.GadgetRender;
  553.     DrawImage(w->RPort, im, obj->wo_CurrentX - cx,
  554.         obj->wo_CurrentY + YOFF - cy);
  555.     if (mode & HIGH) obj->wo_Flags |= HIGH;    /* For use by refresh() */
  556.     else obj->wo_Flags &= ~HIGH;
  557.     icon_txt.IText = obj->wo_Name;
  558.     icon_txt.LeftEdge = obj->wo_NameXOffset;
  559.     icon_txt.TopEdge = obj->wo_NameYOffset;
  560.     PrintIText(w->RPort, &icon_txt, obj->wo_CurrentX - cx,
  561.         obj->wo_CurrentY + YOFF - cy);
  562. }
  563.  
  564. /* Run something */
  565. run(obj) struct MyWBObject *obj; {
  566.     struct WBStartup *msg;
  567.     struct Process *proc;
  568.     long seg, stack;
  569.     struct MsgPort *id;
  570.     struct Node *node;
  571.     char *name, i;
  572.     struct MyWBObject *arg;
  573.     BPTR lock;
  574.  
  575.     if (obj->wo_Type==WBPROJECT) {
  576.         if (!(name = obj->wo_DefaultTool))
  577.         {error("This project has no default tool"); return;}
  578.         if (debug) printf("Default Tool: <%s>\n", name);
  579.     }
  580.     else if (obj->wo_Type==WBTOOL) name = obj->wo_Name;
  581.     if (debug) printf("Running <%s>\n", name);
  582.     if (!obj->wo_Parent) {printf("I've lost my mommy\n"); return;}
  583.     lock = getlock(obj);
  584.     if (debug) printf("run: cd %lx\n", lock);
  585.     CurrentDir(lock);
  586.     if (!(seg = LoadSeg(name)))
  587.         {error("Can't load the tool"); goto runCln;}
  588.     stack = (obj->wo_StackSize) ? obj->wo_StackSize : 5000L;
  589.     if (debug) printf("stack=%ld\n", stack);
  590.     if (!(id = CreateProc(name, 0L, seg, stack)))
  591.         {printf("Can't create a process\n"); goto runCln;}
  592.     proc = (struct Process *)((long)(id) - sizeof(struct Task));
  593.     if (!(msg = ALLOC(WBStartup)))
  594.         {printf("Can't make a msg\n"); goto runCln;}
  595.     msg->sm_Message.mn_ReplyPort = WBPort;
  596.     msg->sm_Process = id;
  597.     msg->sm_Segment = seg;
  598.     msg->sm_NumArgs = 0;
  599.     if (obj->wo_Type==WBPROJECT) msg->sm_NumArgs++;
  600.     for (node=selObjs.lh_Head; node->ln_Succ; node=node->ln_Succ)
  601.         msg->sm_NumArgs++;
  602.     if (debug) printf("%ld args\n",msg->sm_NumArgs);
  603.     if (!(msg->sm_ArgList =
  604.     AllocMem(msg->sm_NumArgs*(long)sizeof(struct WBArg), MEMF_CPC)))
  605.         {printf("Can't allocate arglist\n"); return;}
  606.     i = 0;
  607.     if (obj->wo_Type==WBPROJECT) {
  608.         msg->sm_ArgList[i].wa_Name = name;
  609.         msg->sm_ArgList[i].wa_Lock = Lock(name, ACCESS_READ);
  610.         i++;
  611.     }
  612.     msg->sm_ArgList[i].wa_Name = obj->wo_Name;
  613.     msg->sm_ArgList[i].wa_Lock = lock;
  614.     i++;
  615.     for (node=selObjs.lh_Head; node->ln_Succ; node=node->ln_Succ) {
  616.         arg = OBJ(node,SEL);
  617.         if (arg==obj) continue;
  618.         if (arg->wo_Type==WBTOOL || arg->wo_Type==WBPROJECT)
  619.             msg->sm_ArgList[i].wa_Name = arg->wo_Name;
  620.         else msg->sm_ArgList[i].wa_Name = empty;
  621.         msg->sm_ArgList[i].wa_Lock = getlock(arg);
  622.         if (debug) printf("<%s> %lx\n",
  623.             msg->sm_ArgList[i].wa_Name,
  624.             msg->sm_ArgList[i].wa_Lock);
  625.         /* Wrong for dirs--the lock should be a lock
  626.         on the object itself */
  627.         i++;
  628.     }
  629.     msg->sm_ToolWindow = obj->wo_ToolWindow;
  630.     if (obj->wo_ToolWindow) if (debug)
  631.         printf("ToolWindow:<%s>\n", obj->wo_ToolWindow);
  632.     PutMsg(id, msg);
  633.     toolsRunning++;
  634.     return;
  635. runCln:    if (seg) {
  636.         if (debug) printf("runCln: unloading\n");
  637.         UnLoadSeg(seg);
  638.     }
  639. }
  640.  
  641. void *allocList(obj, size) struct MyWBObject *obj; {
  642.     void *buf;
  643.  
  644.     if (!(buf = AllocMem((long)size, MEMF_CPC)))
  645.         closeAll("Can't allocList");
  646.     AddFreeList(&obj->wo_FreeList, buf, (long)size);
  647.     return buf;
  648. }
  649.  
  650. refresh(w) struct Window *w; {
  651.     struct MyWBObject *obj;
  652.     struct Node *node;
  653.  
  654.     if (debug) printf("Refresh %lx <%s>\n", w, w->Title);
  655.     for (node=wbObjs.lh_Head; node->ln_Succ; node=node->ln_Succ) {
  656.         obj = (struct MyWBObject *) node;
  657.         if (obj->wo_IconWin==w) drawobj(obj, obj->wo_Flags & HIGH);
  658.     }
  659. }
  660.